#include "StdAfx.h"
#include "FMod.h"

DECLARE_SINGLETON_CPP(FMod);

FMod::FMod(void)
{
	//ZeroMemory(this, sizeof(FMod));
	m_p_System = NULL;
}

FMod::~FMod(void)
{
}

void FMod::Init()
{
	if (FMOD::System_Create(&m_p_System) != FMOD_OK)
	{
#if _DEBUG
		assert(false);
#endif
	}
	m_p_System->init(50, FMOD_INIT_NORMAL, NULL);
}

void FMod::Shutdown()
{
	ReleaseAllSounds();
	m_p_System->release();
}

void FMod::Update(float _dt)
{
	if (m_p_System->update() != FMOD_OK)
	{

	}

	static float prevTime = 0.0f;
	prevTime += _dt;

	if (prevTime >= 5.0f)
	{
		// Reduce handle count
		Sounds::iterator end = m_SoundList.end();
		for (Sounds::iterator i = m_SoundList.begin(); i != end; ++i)
		{
			for (list<FMOD::Channel*>::iterator j = (*i)->soundChannels.begin(); j != (*i)->soundChannels.end(); /*++j*/)
			{
				bool playing = false;
				if ((*j)->isPlaying(&playing) != FMOD_OK)
					j = (*i)->soundChannels.erase(j);
				else
					++j;
			}
		}
		prevTime = 0.0f;
	}

}

SoundHandle FMod::AddSound(const string& _file, FMOD_MODE _mode) 
{
	Sounds::iterator end = m_SoundList.end();
	for (Sounds::iterator i = m_SoundList.begin(); i != end; ++i)
	{
		if ((*i)->filename == _file && (*i)->soundFormat == _mode)
		{
			(*i)->AddRef();
			return (*i);
		}
	}
	
	Sound* sound = new Sound();
	sound->filename = _file;
	sound->soundFormat = _mode;
	FMOD_RESULT r;
	if ((r = m_p_System->createSound(_file.c_str(), _mode, NULL, &sound->sound)) != FMOD_OK)
	{
		delete sound;
		return NULL;
	}

	m_SoundList.push_back(sound);

	sound->AddRef();
	return sound;
}

void FMod::ReleaseSound(SoundHandle _id)
{
	// TODO NK
}

void FMod::ReleaseAllSounds()
{
	Sounds::iterator end = m_SoundList.end();
	for (Sounds::iterator i = m_SoundList.begin(); i != end; ++i)
	{
		(*i)->Release();
	}
}

void FMod::PlaySound(SoundHandle _id)
{
	FMOD::Channel* channel;

	if(m_p_System->playSound(FMOD_CHANNEL_FREE, _id->sound , false, &channel) != FMOD_OK) 
	{

	}
	else
	{
		_id->soundChannels.push_back(channel);
		//_id->soundChannels.back()->setVolume(OptionState::GetInstance()->GetSfxVolume());
	}	
}

void FMod::ResetSound(SoundHandle _id)
{

	for (list<FMOD::Channel*>::iterator i = _id->soundChannels.begin(); i != _id->soundChannels.end(); ++i)
	{
		(*i)->setPosition(0, FMOD_TIMEUNIT_MS);
	}
}

void FMod::StopSound(SoundHandle _id)
{
	for (list<FMOD::Channel*>::iterator i = _id->soundChannels.begin(); i != _id->soundChannels.end(); ++i)
	{
		(*i)->stop();
	}
}

void FMod::SetVolume(SoundHandle _id, float _volume)
{
	for (list<FMOD::Channel*>::iterator i = _id->soundChannels.begin(); i != _id->soundChannels.end(); ++i)
	{
		(*i)->setVolume(_volume);
	}
}

void FMod::SetPan(SoundHandle _id, float _pan)
{
	for (list<FMOD::Channel*>::iterator i = _id->soundChannels.begin(); i != _id->soundChannels.end(); ++i)
	{
		(*i)->setPan(_pan);
	}
}

bool FMod::IsSoundPlaying(SoundHandle _id)
{
	bool playing = false;
	for (list<FMOD::Channel*>::iterator i = _id->soundChannels.begin(); i != _id->soundChannels.end(); ++i)
	{
		(*i)->isPlaying(&playing);
		if (playing)
			return true;
	}

	return false;
}



